/*
 * Copyright (C) hushenglan
 */

#include "mysys.h"

namespace mysys
{

/*
 * 构造函数
 */
CProcess::CProcess(process_main_pt routine, void *args)
{
    _routine = routine;
    _args = args;
}

/*
 * 析构函数
 */
CProcess::~CProcess()
{
}

/*
 * 守护进程
 */
int CProcess::daemon()
{
    int fd;
    int pid;

    switch (fork())
    {
        case -1:
            return MS_ERROR;

        case 0:
            break;

        default:
            exit(0);
    }

    pid = getpid();

    if (setsid() == -1)
    {
        return MS_ERROR;
    }

    umask(0);

    fd = open("/dev/null", O_RDWR);
    if (fd == -1)
    {
        return MS_ERROR;
    }

    if (dup2(fd, STDIN_FILENO) == -1)
    {
        return MS_ERROR;
    }

    if (dup2(fd, STDOUT_FILENO) == -1)
    {
        return MS_ERROR;
    }

    if (fd > STDERR_FILENO)
    {
        if (close(fd) == -1)
        {
            return MS_ERROR;
        }
    }

    return MS_OK;
}

/*
 * 启动进程
 */
int CProcess::start()
{
    ms_pid_t pid;

    pid = fork();
    if (pid < 0)
    {
        /* error */
        return MS_ERROR;
    }
    else if (pid > 0)
    {
        /* parent, return */
        return pid;
    }
    else
    {
        /* pid = 0 */
        /* child, never return */
        return processMain();
    }

    return MS_ERROR;
}

/*
 * 进程main函数
 */
int CProcess::processMain()
{
    return (*_routine)(_args);
}

/*
 * 设置进程退出的动作
 */
int CProcess::setAtexit(process_exit_pt func)
{
    int res = -1;

    res = atexit(func);
    if (res != 0)
    {
        /* error */
        return MS_ERROR;
    }

    return MS_OK;
}

/*
 * 获取进程id
 */
ms_pid_t CProcess::getPid()
{
    return getpid();
}

}
